﻿using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHibernate.Cfg.MappingSchema;
using Inovout.Repository.Configuration;

namespace Inovout.Repository
{
    public class SessionFactoryHolder : ISessionFactoryHolder
    {
        private readonly string defaultNHibernateConfigurationKey = "DefaultRepository";
        private IDictionary<object, NHibernate.Cfg.Configuration> nhibernateConfigurationDictionaries;
        private IDictionary<Type, ISessionFactory> sessionFactoryDictionaries;
        public SessionFactoryHolder()
        {
            Initialize();
        }

        public static ISession session;
        public ISession CreateSession(Type type)
        {
            if (session == null)
            {
                session = this.GetSessionFactory(type).OpenSession();
            }
            return session;

        }
        private ISession CreateScopeSession(Type type)
        {
            ISession session;
            ISessionFactory sessionFactory = this.GetSessionFactory(type);
            session = sessionFactory.OpenSession();
            return session;

        }
        public void FailSession(ISession session)
        { }
        public NHibernate.Cfg.Configuration GetNHibernateConfiguration(object obj)
        {
            NHibernate.Cfg.Configuration confg;
            nhibernateConfigurationDictionaries.TryGetValue(obj, out confg);
            return confg;
        }
        public IEnumerable<NHibernate.Cfg.Configuration> GetNHibernateConfigurations()
        {
            IList<NHibernate.Cfg.Configuration> configurations = new List<NHibernate.Cfg.Configuration>();
            foreach (var obj in nhibernateConfigurationDictionaries)
            {
                configurations.Add(obj.Value);
            }
            return configurations.Distinct();
        }
        public ISessionFactory GetSessionFactory(Type type)
        {
            ISessionFactory sessionFactory;
            sessionFactoryDictionaries.TryGetValue(type, out sessionFactory);
            if (sessionFactory == null)
            {
                NHibernate.Cfg.Configuration confg = GetNHibernateConfiguration(type);
                sessionFactory = confg.BuildSessionFactory();
                RegisterSessionFactory(type, sessionFactory);
            }
            return sessionFactory;
        }
        public void Initialize()
        {
            sessionFactoryDictionaries = new Dictionary<Type, ISessionFactory>();
            Persistence persistence = Persistence.GetDefaultPersistence();
            nhibernateConfigurationDictionaries = new Dictionary<object, NHibernate.Cfg.Configuration>();
            if (persistence != null)
            {
                nhibernateConfigurationDictionaries = persistence.CreateNHibernateConfigurations();
            }
        }
        public void RegisterHbmMapping(HbmMapping hbmMapping) { }
        public void RegisterNHibernateConfiguration(object obj, NHibernate.Cfg.Configuration configration)
        {
            this.nhibernateConfigurationDictionaries.Add(obj, configration);
        }
        public void RegisterSessionFactory(Type type, ISessionFactory sessionFactory)
        {
            this.sessionFactoryDictionaries.Add(type, sessionFactory);
        }
        public void ReleaseSession(ISession session)
        {
            session.Flush();
            session.Dispose();
        }

    }
}
